package com.itfreer.data.general.domain;

import com.itfreer.data.general.GlobalDataType;
import com.itfreer.data.general.ITable;
import com.itfreer.data.general.ITableFactory;
import com.itfreer.data.general.RowBase;
import com.itfreer.data.general.TableFactoryClass;
import com.itfreer.data.general.utils.TreeDataUtils;
import com.itfreer.utils.StringUtils;
import com.itfreer.utils.TreeNode;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 定义基于数据表的字典管理类
 */
public class CachedTableDomain implements IDomain {

	private String codeTableName;
	private String codeDomainName;
	private HashMap<String, String> codeValues;
	private List<RowBase> codeValues2;
	private HashMap<String, List<RowBase>> nextData;
	
	public CachedTableDomain(String codeTableName, String codeDomainName, 
			HashMap<String, String> codeValues,
			List<RowBase> codeValues2,
			HashMap<String, List<RowBase>> nextData) {
		this.codeTableName = codeTableName;
		this.codeDomainName = codeDomainName.toUpperCase().trim();
		this.codeValues = codeValues;
		this.codeValues2 = codeValues2;
		this.nextData = nextData;
	}

	/**
	 * 获取字典域别名，用于显示
	 * 
	 * @return
	 */
	@Override
	public String getDomainAliasName() {
		return codeDomainName;
	}

	@Override
	public HashMap<String, String> getDomains() {
		return codeValues;
	}

	private HashMap<String, String[]> codeValuesEx;

	/**
	 * 获取代码值，此值主要用于代码翻译，包括单位的翻译
	 */
	@Override
	public HashMap<String, String[]> getDomainsEx() {
		if (codeValuesEx != null) {
			return codeValuesEx;
		}

		if (StringUtils.IsNullOrSpace(this.getUnitFieldName())) {
			HashMap<String, String> codeValues = getDomains();
			Set<String> keys = codeValues.keySet();
			codeValuesEx = new HashMap<String, String[]>();
			for (String key : keys) {
				String[] value = new String[2];
				value[0] = codeValues.get(key);
				codeValuesEx.put(key, value);
			}
			return codeValuesEx;
		} else {
			codeValuesEx = new HashMap<String, String[]>();
			List<RowBase> codeValues = getDatas();
			for (RowBase row : codeValues) {
				String code = (String) row.getValue(GlobalDataType.String,
						this.getCodeFieldName());
				String caption = (String) row.getValue(GlobalDataType.String,
						this.getCaptionFieldName());
				String unit = (String) row.getValue(GlobalDataType.String,
						this.getUnitFieldName());

				String[] value = new String[2];
				value[0] = caption;
				value[1] = unit;
				codeValuesEx.put(code, value);
			}
			return codeValuesEx;
		}
	}

	@Override
	public List<RowBase> getDatas() {
		if (codeValues2 == null) {
			listEx = null;
			return null;
		} else {
			return codeValues2;
		}
	}

	private List<Map<String, Object>> listEx2 = null;

	/**
	 * 获取所有数据，并转换成可绑定到TreeGrid的数据对象
	 * 
	 * @return
	 */
	@Override
	public List<Map<String, Object>> getDatasEx2(boolean convertStaticField) {

		List<RowBase> rowList = getDatas();
		if (rowList == null) {
			return null;
		}

		listEx2 = TreeDataUtils.GetTreeData(rowList, getIDFieldName(),
                getPIDFieldName(), getIsChildFieldName(), getCodeFieldName(),
                getCaptionFieldName());

		if (convertStaticField) {
			convertStaticField(listEx2, this);
		}

		if (listEx2 == null) {
			listEx2 = new ArrayList<Map<String, Object>>();
		}
		List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
		result.addAll(listEx2);
		return result;
	}

	@SuppressWarnings("unchecked")
	public static void convertStaticField(List<Map<String, Object>> value,
			IDomain pdomain) {
		if (value == null || value.size() <= 0) {
			return;
		}
		for (Map<String, Object> item : value) {
			Set<String> keys = item.keySet();
			List<String> copyKeys = new ArrayList<String>();
			copyKeys.addAll(keys);
			for (String key : copyKeys) {
				if (key.equals("children")) {
					List<Map<String, Object>> children = (List<Map<String, Object>>) item
							.get(key);
					convertStaticField(children, pdomain);
				} else {
					String newKey = "";
					if (key.equals(pdomain.getIDFieldName())) {
						newKey = IDomain.ID;
					} else if (key.equals(pdomain.getPIDFieldName())) {
						newKey = IDomain.PID;
					} else if (key.equals(pdomain.getCodeFieldName())) {
						newKey = IDomain.DOMAINCODE;
					} else if (key.equals(pdomain.getCaptionFieldName())) {
						newKey = IDomain.DOMAINCAPTION;
					} else if (key.equals(pdomain.getDomainFieldName())) {
						newKey = IDomain.DOMAINNAME;
					} else if (key.equals(pdomain.getLevelFieldName())) {
						newKey = IDomain.JB;
					} else if (key.equals(pdomain.getIsChildFieldName())) {
						newKey = IDomain.ISCHILD;
					} else if (key.equals(pdomain.getIsEditFieldName())) {
						newKey = IDomain.ISEDIT;
					} else if (key.equals(pdomain.getIsUsedFieldName())) {
						newKey = IDomain.ISUSER;
					} else if (key.equals(pdomain.getOrderFieldName())) {
						newKey = IDomain.ORDER;
					} else if (key.equals(pdomain.getUnitFieldName())) {
						newKey = IDomain.UNIT;
					}
					if (newKey != "") {
						Object itemObject = item.get(key);
						item.remove(key);
						item.put(newKey, itemObject);
					}
				}
			}
		}
	}

	private List<TreeNode> listEx;

	/**
	 * 获取所有数据，并转换成可绑定的数据对象
	 * 
	 * @return
	 */
	public List<TreeNode> getDatasEx() {
		List<RowBase> rowList = getDatas();
		if (rowList == null) {
			return null;
		}
		listEx = TreeDataUtils.GetTreeData(rowList, this.getIDFieldName(),
				this.getPIDFieldName(), this.getCodeFieldName(),
				this.getCaptionFieldName());

		if (listEx == null) {
			listEx = new ArrayList<TreeNode>();
		}

		List<TreeNode> result = new ArrayList<TreeNode>();
		result.addAll(listEx);
		return result;
	}

	/**
	 * 带政区ID的字典过滤
	 */
	@Override
	public List<TreeNode> getDatasEx(HashMap<String, Object> filterMap,
			String extKey, String extVal) {
		List<RowBase> rowList = getDatas();
		if (rowList == null) {
			return null;
		}
		rowList = filterResultByRight(rowList, filterMap, extKey, extVal);
		List<TreeNode> result = new ArrayList<TreeNode>();
		result = TreeDataUtils.GetTreeData(rowList, this.getIDFieldName(),
				this.getPIDFieldName(), this.getCodeFieldName(),
				this.getCaptionFieldName());
		return result;
	}

	@Override
	public List<TreeNode> getDatasEx(HashMap<String, Object> filterMap) {
		List<RowBase> rowList = getDatas();
		if (rowList == null) {
			return null;
		}
		rowList = filterResult(rowList, filterMap);
		List<TreeNode> result = new ArrayList<TreeNode>();
		result = TreeDataUtils.GetTreeData(rowList, this.getIDFieldName(),
				this.getPIDFieldName(), this.getCodeFieldName(),
				this.getCaptionFieldName());
		return result;
	}

	/**
	 * 按过滤条件过滤数据
	 *
	 * @param filterMap
	 * @return
	 */
	@SuppressWarnings("rawtypes")
	private List<RowBase> filterResultByRight(List<RowBase> rowList,
			HashMap<String, Object> filterMap, String extKey, String extVal) {
		List<RowBase> filterResult = new ArrayList<RowBase>();
		for (RowBase row : rowList) {
			Set keyArray = filterMap.keySet();
			Iterator iterator = keyArray.iterator();
			while (iterator.hasNext()) {
				String key = iterator.next().toString();
				String rowValue = (String) row.getValue(key);
				String value = (String) filterMap.get(key);
				String _extValue = (String) row.getValue(extKey);
				if (!StringUtils.IsNullOrSpace(rowValue)
						&& rowValue.equals(value)
						&& _extValue.startsWith(extVal)) {
					filterResult.add(row);
				} else {
					if (filterResult.contains(row)) {
						filterResult.remove(row);
					}
				}
			}
		}
		return filterResult;
	}

	/**
	 * 按过滤条件过滤数据
	 *
	 * @param filterMap
	 * @return
	 */
	@SuppressWarnings("rawtypes")
	private List<RowBase> filterResult(List<RowBase> rowList,
			HashMap<String, Object> filterMap) {
		List<RowBase> filterResult = new ArrayList<RowBase>();
		for (RowBase row : rowList) {
			Set keyArray = filterMap.keySet();
			Iterator iterator = keyArray.iterator();
			while (iterator.hasNext()) {
				String key = iterator.next().toString();
				String rowValue = (String) row.getValue(key);
				String value = (String) filterMap.get(key);
				if (!StringUtils.IsNullOrSpace(rowValue)
						&& rowValue.equals(value)) {
					filterResult.add(row);
				} else {
					if (filterResult.contains(row)) {
						filterResult.remove(row);
					}
				}
			}
		}
		return filterResult;
	}

	@Override
	public List<RowBase> getNextDatas(String id) {
		if (nextData == null) {
			nextListEx = null;
			return null;
		} else {
			if (nextData.containsKey(id)) {
				List<RowBase> rowList = nextData.get(id);
				List<RowBase> result = new ArrayList<RowBase>();
				result.addAll(rowList);
				return result;
			} else {
				return null;
			}
		}
	}

	private HashMap<String, List<TreeNode>> nextListEx;

	/**
	 * 获取下级数据对象，并转换成可绑定对象
	 * 
	 * @param id
	 * @return
	 */
	public List<TreeNode> getNextDatasEx(String id) {
		if (nextListEx != null && nextListEx.containsKey(id)) {
			List<TreeNode> list = nextListEx.get(id);

			List<TreeNode> result = new ArrayList<TreeNode>();
			result.addAll(list);
			return result;
		}

		List<RowBase> rowList = getNextDatas(id);
		if (rowList == null) {
			return null;
		}
		List<TreeNode> list = TreeDataUtils.GetTreeData(rowList,
				this.getIDFieldName(), this.getPIDFieldName(),
				this.getCodeFieldName(), this.getCaptionFieldName());
		if (nextListEx == null) {
			nextListEx = new HashMap<String, List<TreeNode>>();
		}
		nextListEx.put(id, list);

		List<TreeNode> result = new ArrayList<TreeNode>();
		result.addAll(list);
		return result;
	}

	public ITable getCodeTable() {
		ITableFactory tableFactory = TableFactoryClass.install;
		return tableFactory.openTable(this.codeTableName);
	}

	@Override
	public String getIDFieldName() {
		return getCodeTable().getIDFieldName();
	}

	@Override
	public String getPIDFieldName() {
		return getCodeTable().getPIDFieldName();
	}

	@Override
	public String getCodeFieldName() {
		return getCodeTable().getCodeFieldName();
	}

	@Override
	public String getCaptionFieldName() {
		return getCodeTable().getCaptionFieldName();
	}

	@Override
	public String getOrderFieldName() {
		return getCodeTable().getOrderFieldName();
	}

	@Override
	public String getIsUsedFieldName() {
		return getCodeTable().getIsUsedFieldName();
	}

	@Override
	public String getIsEditFieldName() {
		return getCodeTable().getIsEditFieldName();
	}

	/**
	 * 获取单位字段
	 */
	@Override
	public String getUnitFieldName() {
		return getCodeTable().getUnitFieldName();
	}

	@Override
	public String getLevelFieldName() {
		return getCodeTable().getLevelFieldName();
	}

	@Override
	public String getDomainFieldName() {
		return getCodeTable().getDomainFieldName();
	}

	@Override
	public String getIsChildFieldName() {
		return getCodeTable().getIsChildFieldName();
	}

	@Override
	public DomainType getDomainType() {
		return getCodeTable().getDomainType();
	}
}